package com.iyue.user;

import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.lang.StringUtils;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionRedirect;

import com.iyue.SpringHelper;
import com.iyue.core.pojo.UserAccount;
import com.iyue.core.service.CoreBiz;
import com.iyue.framework.BaseAction;
import com.iyue.framework.cache.IMemcachedCache;
import com.iyue.framework.secu.MD5;
import com.iyue.log.pojo.EmailLog;
import com.iyue.log.service.EmailBiz;
import com.iyue.servlet.taglibs.Functions;
import com.iyue.sys.pojo.SysCity;
import com.iyue.sys.pojo.SysProvince;
import com.iyue.sys.service.Keyword;
import com.iyue.user.helper.UserUtil;
import com.iyue.user.pojo.UserBasic;
import com.iyue.user.pojo.UserProtect;
import com.iyue.user.service.UserBiz;
import com.iyue.util.ValidCode;
import com.iyue.util.file.FileUpload;
import com.iyue.util.file.FileUtil;

/**
 * 《网站注册》实现类
 *
 * @author 孙晓晔
 * @version $Id: Reg.java,v 1.1 2010/10/14 17:07:17 fresh Exp $
 */
public class User extends UserUtil {

	/**
	 * email当天发送标示
	 */
	private static final String USER_PROTECT_LIMIT = "com.iyue.pojo.email_log_datetime_";

	/**
	 * 查看用户资料
	 */
	public ActionForward layout(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response,
			BaseAction action) throws Exception {
		Integer uid = username(request);
		if (uid == null) {
			return action.display(request, response, "login");
		}

		return action.display(request, response, "profile");
	}

	/**
	 *
	 * @param mapping
	 * @param form
	 * @param request
	 * @param response
	 * @param action
	 * @return
	 * @throws Exception
	 */
	public ActionForward changeCity(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response,
			BaseAction action) throws Exception {
		if (!isLogin(request)) {
			return action.display(request, response, "login");
		}

		return action.display(request, response, "user_city");
	}

	/**
	 * 修改用户基本信息
	 */
	public ActionForward basic(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response,
			BaseAction action) throws Exception {
		if (!isLogin(request)) {
			return action.display(request, response, "login");
		}

		Integer username = u(request);

		UserBiz biz = (UserBiz) SpringHelper.getBean("UserBiz");
		String owner = username.toString();
		UserBasic profile = biz.profile(owner);
		if (profile != null) {
			request.setAttribute("basic", profile);
		}
		//hgl add
		List<SysProvince> result = Functions.provinces();
		request.setAttribute("provinces", result);
		return action.display(request, response, "basic");
	}

	/**
	 * 修改基本信息
	 */
	public ActionForward photo(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response,
			BaseAction action) throws Exception {
		if (!isLogin(request)) {
			return action.display(request, response, "login");
		}

		return action.display(request, response, "photo");
	}

	protected Map<String, String> map(HttpServletRequest request,
			String username) throws UnsupportedEncodingException {
		Map<String, String> ret = null;

		if (ServletFileUpload.isMultipartContent(request)) {
			ret = FileUtil.upload(request, FileUpload.FILE_TYPE_IMAGE, username
					.toString());

			if (ret == null) {
				return null;
			}

		} else {
			String picurl = request.getParameter("upfile");
			ret = new HashMap<String, String>();
			ret.put("upfile", picurl);
		}

		return ret;
	}

	/**
	 * 省份列表
	 */
	public ActionForward provinces(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response,
			BaseAction action) throws Exception {
		if (!isLogin(request)) {
			return action.display(request, response, "login");
		}

		List<SysProvince> result = Functions.provinces();

		request.setAttribute("provinces", result);

		return action.display(request, response, "provinces");
	}

	/**
	 * 根据省份ID获取城市列表
	 */
	public ActionForward cities(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response,
			BaseAction action) throws Exception {
		if (!isLogin(request) && StringUtils.isEmpty(request.getParameter("ajax"))) {
			return action.display(request, response, "login");
		}

		String forward = request.getParameter("go");
		if (forward != null && forward.indexOf("&msg") > 0) {
			forward = forward.substring(0, forward.indexOf("&msg"));
		}

		String pid = request.getParameter("pid");
		if (StringUtils.isBlank(pid)) {
			request.setAttribute("msg", "请选择省份");
			return new ActionForward(forward + "&msg="
					+ Functions.encode("请选择省份"), true);
		}

		List<SysCity> result = Functions.getCityByPid(pid);

		request.setAttribute("cities", result);

		return action.display(request, response, "cities");
	}

	/**
	 * 修改居住地
	 */
	public ActionForward quick(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response,
			BaseAction action) throws Exception {
		if (!isLogin(request)) {
			return action.display(request, response, "login");
		}

		String forward = request.getParameter("go");
		if (forward != null && forward.indexOf("&msg") > 0) {
			forward = forward.substring(0, forward.indexOf("&msg"));
		}

		Integer username = u(request);
		String sc = request.getParameter("sc");
		if (StringUtils.isBlank(sc)) {
			// request.setAttribute("msg", "请选择城市");
			return new ActionForward(forward + "&msg="
					+ Functions.encode("请选择城市"), true);
		}

		String[] scs = sc.split("-");
		if (scs == null || scs.length < 2) {
			return new ActionForward(forward + "&msg="
					+ Functions.encode("请选择城市"), true);
		}

		UserBiz biz = (UserBiz) SpringHelper.getBean("UserBiz");
		int ret = biz.update_basic_address(username, scs[0], scs[1]);

		String msg = "";
		if (ret < 0) {
			msg = "修改失败!";
		} else {
			msg = "修改成功!";
		}

		return new ActionRedirect(url(request, "user.do", "do=User.basic&msg="
				+ Functions.encode(msg)));
	}

	/**
	 * 修改居住地
	 */
	public ActionForward address(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response,
			BaseAction action) throws Exception {
		if (!isLogin(request)) {
			return action.display(request, response, "login");
		}

		String forward = request.getParameter("go");
		if (forward != null && forward.indexOf("&msg") > 0) {
			forward = forward.substring(0, forward.indexOf("&msg"));
		}

		Integer username = u(request);
		UserBasic user = new UserBasic();
		user.setUsername(username);

		String province = request.getParameter("pid");
		if (StringUtils.isBlank(province)) {
			request.setAttribute("msg", "请选择省份");
			return new ActionForward(forward + "&msg="
					+ Functions.encode("请选择省份"), true);
		}

		String city = request.getParameter("cid");
		if (StringUtils.isBlank(city)) {
			request.setAttribute("msg", "请选择城市");
			return new ActionForward(forward + "&msg="
					+ Functions.encode("请选择城市"), true);
		}

		user.setProvince(province);
		user.setCity(city);

		UserBiz biz = (UserBiz) SpringHelper.getBean("UserBiz");
		int ret = biz.update_basic_address(username, province, city);

		String msg = "";
		if (ret < 0) {
			msg = "修改失败!";
		} else {
			msg = "修改成功!";
		}

		return new ActionRedirect(url(request, "user.do", "do=User.basic&msg="
				+ Functions.encode(msg)));
	}

	/**
	 * 修改基本信息
	 */
	public ActionForward basicPost(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response,
			BaseAction action) throws Exception {
		if (!isLogin(request)) {
			return action.display(request, response, "login");
		}

		Integer username = u(request);

		UserBasic user = new UserBasic();
		user.setUsername(username);
		String nickname = request.getParameter("nickname");
		if (StringUtils.isBlank(nickname)) {
			request.setAttribute("msg", "请输入昵称!");
			return basic(mapping, form, request, response, action);
		}

		nickname = nickname.trim();
		if (nickname.length() < 2) {
			request.setAttribute("msg", "输入昵称过短，请重新输入！");
			return basic(mapping, form, request, response, action);
		}

		if (nickname.length() > 16) {
			request.setAttribute("msg", "输入昵称过长，请重新输入！");
			return basic(mapping, form, request, response, action);
		}

		String sex = request.getParameter("sex");
		if (StringUtils.isBlank(sex)) {
			request.setAttribute("msg", "请选择性别!");
			return basic(mapping, form, request, response, action);
		}

		user.setSex(new Integer(sex));

		Keyword key = (Keyword) SpringHelper.getBean("Keyword");
		if (key.isIllegal(nickname)) {
			request.setAttribute("msg", "对不起，您不能用此昵称！");
			return basic(mapping, form, request, response, action);
		}

		user.setNickname(nickname);

		UserBiz biz = (UserBiz) SpringHelper.getBean("UserBiz");
		UserBasic basic = biz.basic(username);
		int ret = -1;
		if (basic == null) {
			ret = biz.save_basic(user);
		} else {
			ret = biz.update_basic(user);
		}

		String msg = "";
		if (ret < 0) {
			msg = "修改失败!";
		} else {
			msg = "修改成功!";
		}

		return new ActionRedirect(url(request, "user.do", "do=User.basic&msg="
				+ Functions.encode(msg)));
	}
	public ActionForward basicPostAjax(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response,
			BaseAction action) throws Exception {
		response.setContentType("text/html;charset=UTF-8");
		response.setHeader("Cache-Control", "no-cache");
		if (!isLogin(request)) {
			return action.display(request, response, "login");
		}

		Integer username = u(request);

		UserBasic user = new UserBasic();
		user.setUsername(username);
		String nickname = request.getParameter("nickname");
		if (StringUtils.isBlank(nickname)) {
			String msg = "请输入昵称!";
			response.getWriter().write(msg);
			return null;
		}

		nickname = nickname.trim();
		if (nickname.length() < 2) {
			String msg = "输入昵称过短，请重新输入！";
			response.getWriter().write(msg);
			return null;
		}

		if (nickname.length() > 16) {
			String msg = "输入昵称过长，请重新输入！";
			response.getWriter().write(msg);
			return null;
		}

		String sex = request.getParameter("sex");
		if (StringUtils.isBlank(sex)) {
			String msg = "请选择性别!";
			response.getWriter().write(msg);
			return null;
		}

		user.setSex(new Integer(sex));

		Keyword key = (Keyword) SpringHelper.getBean("Keyword");
		if (key.isIllegal(nickname)) {
			String msg = "对不起，您不能用此昵称！";
			response.getWriter().write(msg);
			return null;
		}

		user.setNickname(nickname);

		UserBiz biz = (UserBiz) SpringHelper.getBean("UserBiz");
		UserBasic basic = biz.basic(username);
		int ret = -1;
		if (basic == null) {
			ret = biz.save_basic(user);
		} else {
			ret = biz.update_basic(user);
		}

		String msg = "";
		if (ret < 0) {
			msg = "修改失败!";
		} else {
			msg = "修改成功!";
		}
 		response.getWriter().write(msg);
		return null;
	}

	/**
	 * 绑定邮箱，为了找回密码(密码保护邮箱)
	 */
	public ActionForward protectPost(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response,
			BaseAction action) throws Exception {
		if (!isLogin(request)) {
			return action.display(request, response, "login");
		}

		String backurl = request.getParameter("go");
		if (StringUtils.isBlank(backurl)) {
			backurl = "/user.do?do=User.basic";
		}

		String email = request.getParameter("email");
		if (!isEmail(email)) {
			request.setAttribute("msg", "请输入正确的email地址");
			return basic(mapping, form, request, response, action);
		}

		Integer username = u(request);

		String msg = "";
		UserBiz biz = (UserBiz) SpringHelper.getBean("UserBiz");
		String aa = biz.getUserProtectEmail(username);
		if (!StringUtils.isBlank(aa)) {
			msg = "你已经填写过密码保护邮箱了!";
			Redirect(request, response, backurl + "&msg="
					+ Functions.encode(msg));
			return null;
		}

		UserProtect up = new UserProtect();
		up.setUsername(username);
		up.setEmail(email);
		Date now = new Date();
		up.setCreatetime(now);
		up.setModifytime(now);

		int ret = biz.update_mail_password(username, email);
		if (ret < 1) {
			ret = biz.save_protect(up);
		}

		msg = "操作成功!";

		Redirect(request, response, backurl + "&msg=" + Functions.encode(msg));
		return null;
	}
	public ActionForward protectPostAjax(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response,
			BaseAction action) throws Exception {
		response.setContentType("text/html;charset=UTF-8");
		response.setHeader("Cache-Control", "no-cache");
		if (!isLogin(request)) {
			return action.display(request, response, "login");
		}		 

		String email = request.getParameter("email");
		if (!isEmail(email)) {
			String msg = "请输入正确的email地址";
			response.getWriter().write(msg);
			return null;
		}

		Integer username = u(request);

		String msg = "";
		UserBiz biz = (UserBiz) SpringHelper.getBean("UserBiz");
		String aa = biz.getUserProtectEmail(username);
		if (!StringUtils.isBlank(aa)) {
			msg = "你已经填写过密码保护邮箱了!";
 			response.getWriter().write(msg);
			return null;
		}

		UserProtect up = new UserProtect();
		up.setUsername(username);
		up.setEmail(email);
		Date now = new Date();
		up.setCreatetime(now);
		up.setModifytime(now);

		int ret = biz.update_mail_password(username, email);
		if (ret < 1) {
			ret = biz.save_protect(up);
		}
		msg = "操作成功!";
		response.getWriter().write(msg);
		return null;
	}

	/**
	 * 修改密码
	 */
	public ActionForward passwordPost(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response,
			BaseAction action) throws Exception {
		if (!isLogin(request)) {
			return action.display(request, response, "login");
		}

		String oldpwd = request.getParameter("oldpassword");
		String newpwd = request.getParameter("newpassword");
		String confirm = request.getParameter("confirm");

		if (StringUtils.isBlank(oldpwd)) {
			request.setAttribute("msg", "请输入原始密码!");
			return basic(mapping, form, request, response, action);
		}

		if (StringUtils.isBlank(newpwd)) {
			request.setAttribute("msg", "请输入新密码!");
			return basic(mapping, form, request, response, action);
		}

		if (StringUtils.isBlank(confirm)) {
			request.setAttribute("msg", "请输入确认密码!");
			return basic(mapping, form, request, response, action);
		}

		newpwd = newpwd.trim();
		if (!newpwd.equals(confirm.trim())) {
			request.setAttribute("msg", "两次密码输入不一致！");
			return basic(mapping, form, request, response, action);
		}

		if (!newpwd.matches("(\\d|\\w){6,16}")) {
			request.setAttribute("msg", "密码必须要以字母或数字的组合！");
			return basic(mapping, form, request, response, action);
		}

		if (newpwd.length() > 16) {
			request.setAttribute("msg", "输入密码过长，请重新输入！");
			return basic(mapping, form, request, response, action);
		}

		int cp = checkPasswd(newpwd);
		if (cp > UserAccount.PASSWORD_REGULAR) {
			if (cp == UserAccount.PASSWORD_NULL) {
				request.setAttribute("msg", "密码不能为空！");
			}
			if (cp == UserAccount.PASSWORD_LENGTH) {
				request.setAttribute("msg", "输入密码过短，请重新输入！");
			}
			if (cp == UserAccount.PASSWORD_SIMPLE) {
				request.setAttribute("msg", "密码过于简单，请重新输入！");
			}

			return basic(mapping, form, request, response, action);
		}

		CoreBiz biz = (CoreBiz) SpringHelper.getBean("CoreBiz");
		Integer username = u(request);
		UserAccount account = biz.getUserAccountByUid(username);
		String pass = account.getPassword();
		if (StringUtils.isBlank(pass)) {
			request.setAttribute("msg", "系统异常,请稍后再试!");
			return basic(mapping, form, request, response, action);
		}
		MD5 md5 = new MD5();
		String password = md5.getMD5ofStr(oldpwd);
		if (!password.equals(pass)) {
			request.setAttribute("msg", "旧密码输入错误！");
			return basic(mapping, form, request, response, action);
		}

		int ret = biz.updatePasswordByUid(username, newpwd);
		if (ret > 0) {
			request.setAttribute("msg", "密码修改成功！");
		} else {
			request.setAttribute("msg", "密码修改失败！");
		}

		return basic(mapping, form, request, response, action);
	}
	public ActionForward passwordPostAjax(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response,
			BaseAction action) throws Exception {
		response.setContentType("text/html;charset=UTF-8");
		response.setHeader("Cache-Control", "no-cache");
		if (!isLogin(request)) {
			return action.display(request, response, "login");
		}

		String oldpwd = request.getParameter("oldpassword");
		String newpwd = request.getParameter("newpassword");
		String confirm = request.getParameter("confirm");

		if (StringUtils.isBlank(oldpwd)) {
 			String msg = "请输入原始密码!";
			response.getWriter().write(msg);
			return null;
		}

		if (StringUtils.isBlank(newpwd)) {
 			String msg = "请输入新密码!";
			response.getWriter().write(msg);
			return null;
		}

		if (StringUtils.isBlank(confirm)) {
			String msg = "请输入确认密码!";
			response.getWriter().write(msg);
			return null;
		}

		newpwd = newpwd.trim();
		if (!newpwd.equals(confirm.trim())) {
            String msg = "两次密码输入不一致！";
			response.getWriter().write(msg);
			return null;
		}

		if (!newpwd.matches("(\\d|\\w){6,16}")) {
			String msg = "密码必须要以字母或数字的组合！";
			response.getWriter().write(msg);
			return null;
		}

		if (newpwd.length() > 16) {
			String msg = "输入密码过长，请重新输入！";
			response.getWriter().write(msg);
			return null;
		}

		int cp = checkPasswd(newpwd);
		if (cp > UserAccount.PASSWORD_REGULAR) {
			String msg = "";
			if (cp == UserAccount.PASSWORD_NULL) {
				msg = "密码不能为空！";
			}
			if (cp == UserAccount.PASSWORD_LENGTH) {
				msg = "输入密码过短，请重新输入！";
			}
			if (cp == UserAccount.PASSWORD_SIMPLE) {
				msg = "密码过于简单，请重新输入！";
			}
			response.getWriter().write(msg);
			return null;
		}

		CoreBiz biz = (CoreBiz) SpringHelper.getBean("CoreBiz");
		Integer username = u(request);
		UserAccount account = biz.getUserAccountByUid(username);
		String pass = account.getPassword();
		if (StringUtils.isBlank(pass)) {
			String msg = "系统异常,请稍后再试!";
			response.getWriter().write(msg);
			return null;
		}
		MD5 md5 = new MD5();
		String password = md5.getMD5ofStr(oldpwd);
		if (!password.equals(pass)) {
			String msg = "旧密码输入错误！";
			response.getWriter().write(msg);
			return null;
		}

		int ret = biz.updatePasswordByUid(username, newpwd);
		String msg ="";
		if (ret > 0) {
			msg = "密码修改成功！";
		} else {
			msg = "密码修改失败！";
		}

		response.getWriter().write(msg);
		return null;
	}

	/**
	 * 找回密码页面
	 */
	public ActionForward findPassword(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response,
			BaseAction action) throws Exception {

		return action.display(request, response, "findPassword");
	}

	/**
	 * 找回密码
	 */
	public ActionForward findPasswordPost(ActionMapping mapping,
			ActionForm form, HttpServletRequest request,
			HttpServletResponse response, BaseAction action) throws Exception {

		String account = request.getParameter("username");
		if (StringUtils.isBlank(account)) {
			request.setAttribute("msg", "请输入账号!");
			return action.display(request, response, "findPassword");
		}

		String code = request.getParameter("vcode");
		if (StringUtils.isBlank(code)) {
			request.setAttribute("msg", "验证码不正确！");
			return action.display(request, response, "findPassword");
		}

		String vkey = request.getParameter("vkey");
		if (StringUtils.isBlank(vkey)) {
			request.setAttribute("msg", "验证码不正确！");
			return action.display(request, response, "findPassword");
		}

		// 对比验证码
		if (!ValidCode.isValid(vkey, code)) {
			request.setAttribute("msg", "验证码不正确！");
			return action.display(request, response, "findPassword");
		}

		CoreBiz biz = (CoreBiz) SpringHelper.getBean("CoreBiz");
		Integer username = biz.getUsernameByAccount(account);
		if (username == null) {
			request.setAttribute("msg", "账号不存在!");
			return action.display(request, response, "findPassword");
		}

		if (limit(username)) {
			request.setAttribute("msg", "密码每天只能重置一次!");
			return action.display(request, response, "findPassword");
		}

		UserBiz user_biz = (UserBiz) SpringHelper.getBean("UserBiz");
		String email = user_biz.getUserProtectEmail(username);
		if (StringUtils.isBlank(email)) {
			request.setAttribute("msg", "找回密码邮箱不存在!");
			return action.display(request, response, "findPassword");
		}

		String pwd = login_code();// 生成随机密码
		int ret = biz.updatePasswordByUid(username, pwd);
		if (ret > 0) {
			EmailBiz emailbiz = (EmailBiz) SpringHelper.getBean("EmailBiz");
			EmailLog log = new EmailLog(username, email);
			log.setContent(account + ":您的重置密码为：" + pwd);
			ret = emailbiz.save_email(log);
		}

		if (ret > 0) {
			addLimit(username);
			String msg = "新密码已发送至您的邮箱!<br/>请找回密码后，尽快重置密码！";
			return new ActionForward("/portal.do?do=Portal.layout&msg="
					+ Functions.encode(msg), true);
		}

		request.setAttribute("msg", "重置失败！");

		return action.display(request, response, "findPassword");
	}

	public static String date(Date date, String format) {
		if (date == null) {
			return "";
		}

		SimpleDateFormat sdf = new SimpleDateFormat(format);

		return sdf.format(date.getTime()).trim();
	}

	/**
	 * 用户限制每天只能重置密码一次
	 */
	private boolean limit(Integer username) {
		if (username == null) {
			return false;
		}
		IMemcachedCache cache = (IMemcachedCache) SpringHelper
				.getBean("LogIMemcachedCache");
		Date now = new Date();
		String key = USER_PROTECT_LIMIT + "_" + username + "_"
				+ date(now, "yyyyMMdd");
		Object obj = cache.get(key);
		if (obj != null) {
			if (obj instanceof Integer) {
				return true;
			} else {
				cache.delete(key);
			}
		}

		return false;
	}

	/**
	 * 限制用户找回密码次数
	 *
	 * @param username
	 */
	private void addLimit(Integer username) {
		if (username == null) {
			return;
		}

		IMemcachedCache cache = (IMemcachedCache) SpringHelper
				.getBean("LogIMemcachedCache");

		Date now = new Date();
		String key = USER_PROTECT_LIMIT + "_" + username + "_"
				+ date(now, "yyyyMMdd");

		cache.add(key, 1, IMemcachedCache.DAY);
		return;
	}

}
